package com.nwpu.am.controller.admin;

import com.nwpu.am.constant.ErrorConstant;
import com.nwpu.am.constant.KnowledgeTypeConstant;
import com.nwpu.am.pojo.dto.RuleDTO;
import com.nwpu.am.pojo.dto.page.RulePageDTO;
import com.nwpu.am.pojo.entity.Rule;
import com.nwpu.am.pojo.entity.Knowledge;
import com.nwpu.am.result.PageResult;
import com.nwpu.am.result.Result;
import com.nwpu.am.service.KnowledgeService;
import com.nwpu.am.service.RuleService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.Objects;

/**
 * RuleController
 *
 * @author Fbf
 * @version 1.0
 * {@code @date} 2024/6/6
 */

@RestController
@RequestMapping("/rule")
@Slf4j
@Api(tags = "推理规则接口")
public class RuleController {

    @Resource
    private RuleService ruleService;
    @Resource
    private KnowledgeService knowledgeService;

    @GetMapping("/selectPage")
    @ApiOperation("展示推理规则")
    public Result<PageResult<Rule>> page(RulePageDTO rulePageDTO) {
        log.info("推理规则分页查询，参数为：{}", rulePageDTO);
        PageResult<Rule> pageResult = ruleService.pageQuery(rulePageDTO);
        return Result.success(pageResult);
    }

    @PostMapping("/add")
    @ApiOperation("添加推理规则")
    public Result<String> add(@RequestBody @Validated RuleDTO ruleDTO) {
        long premise = ruleDTO.getPremiseKnowledgeId();
        long conclusion = ruleDTO.getConclusionKnowledgeId();
        // 前提和推论不能相同
        if (premise == conclusion) return Result.error(ErrorConstant.SAME_KNOWLEDGE);
        Knowledge premiseK = knowledgeService.selectById(premise);
        Knowledge conclusionK = knowledgeService.selectById(conclusion);
        // 如果前提和推论都存在
        if (premiseK != null && conclusionK != null) {
            // 检查前提和结论类型
            if (premiseK.getType() != KnowledgeTypeConstant.TRUTH
                    || conclusionK.getType() != KnowledgeTypeConstant.METHOD) {
                return Result.error(ErrorConstant.WRONG_TYPE);
            }
            return ruleService.addRule(ruleDTO) == 1 ?
                    Result.success() :
                    Result.error(ErrorConstant.ADD_WRONG);
        } else {
            return Result.error(ErrorConstant.UNEXPECTED_RULE);
        }
    }

    @DeleteMapping("/delete/{ruleId}")
    @ApiOperation("删除规则")
    public Result<String> deleteById(@PathVariable("ruleId") Long ruleId) {
        return ruleService.deleteRule(ruleId) == 1 ?
                Result.success() :
                Result.error(ErrorConstant.DELETE_WRONG);
    }

    @GetMapping("/select/{ruleId}")
    @ApiOperation("查找规则")
    public Result<Rule> selectById(@PathVariable("ruleId") Long ruleId) {
        return Result.success(ruleService.selectById(ruleId));
    }

    @PutMapping("/update")
    @ApiOperation("修改规则")
    public Result<String> update(@RequestBody @Validated Rule rule) {
        // 查询前提和结论
        Long premise = rule.getPremiseKnowledgeId();
        Long conclusion = rule.getConclusionKnowledgeId();
        if (premise != null && conclusion != null && (Objects.equals(premise, conclusion))) {
            return Result.error(ErrorConstant.SAME_KNOWLEDGE);
        }

        Result<String> pr = checkKnowledgeType(premise, KnowledgeTypeConstant.TRUTH);
        if (pr!=null) {
            return pr;
        }
        Result<String> cr = checkKnowledgeType(premise, KnowledgeTypeConstant.METHOD);
        if (cr!=null) {
            return cr;
        }

        // 更新rule
        return ruleService.update(rule) == 1 ?
                Result.success() :
                Result.error(ErrorConstant.UPDATE_WRONG);
    }

    /**
     * 检查知识类型
     *
     * @param knowledgeId
     * @param type
     * @return
     */
    public Result<String> checkKnowledgeType(Long knowledgeId, short type) {
        if (knowledgeId != null) {
            Knowledge knowledge = knowledgeService.selectById(knowledgeId);
            // 如果知识都存在
            if (knowledge != null) {
                // 检查知识类型
                if (knowledge.getType() != type) {
                    return Result.error(ErrorConstant.WRONG_TYPE);
                }
            } else {
                return Result.error(ErrorConstant.UNEXPECTED_RULE);
            }
        }
        return null;
    }
}